#ifndef DATABASE_H
#define DATABASE_H


#include "GameServer.h"

#include "_Global/Socket/Server/IOCPDllClass/IOCP_Pleafles.h"
#include "_Global/GlobalClass.h"

#include <QObject>



class Mysql;


//耗时任务（数据库操作等）
//!!!注意注入!!!
class Database : public LongTask
{
    Q_OBJECT
public:
    explicit Database();
    virtual ~Database();

    virtual int _init() Q_DECL_OVERRIDE;
    virtual int _release() Q_DECL_OVERRIDE;


signals:
    void s_Critical(int code, QString msg);

    void s_QueryUserFinished(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba, _GameUserData gameUserData = _GameUserData());
    void s_RegisterUserFinished(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba, _GameUserData gameUserData = _GameUserData());

    void s_GetGameServerInfoToBufferFinished(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba);

    void s_GetGameUserInfoToBufferFinished(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba, _GameUserData gameUserData = _GameUserData());
    void s_RegisterGameUserFinished(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba, _GameUserData gameUserData = _GameUserData());

    void s_SetClientShareExtraGameData(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba);

    void s_UpdateScoreFinished(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba, qint32 scoreAdd = 0);

    void s_SetClientGameData(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba);
    void s_GetClientGameData(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba);
    void s_DeleteClientGameData(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba);

    void s_InsertClientData(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba);
    void s_UpdateClientData(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba);

    void s_DBQuery(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba);

    //void s_GetPetsInfoToBufferFinished(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba, _GameUserData gameUserData = _GameUserData());
    /*void s_RegisterFinished(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba);
    void s_GetGameClassInfoToBufferFinished(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba);
    void s_GetGameUserStudyInfoToBufferFinished(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba);
    void s_GetGameUserRankingToBufferFinished(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba);
    void s_GetGameUserItemsToBufferFinished(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba);
    void s_SaveUserStudyResultFinished(_SocketInfo::_SocketContext socketContext, int code, QString msg, QByteArray ba);
    */

public slots:
    //[ok!]
    //查询用户,参数为 pClientInfo的m_strUserName 和 密码,找到后 设置 pClientInfo的id
    //返回0:成功,1:用户名不对,2:密码不对;<0:服务器/数据库错误
    int sl_QueryUser(QString userName, QString password
                     , QByteArray ba, _SocketInfo::_SocketContext socketContext);

    //注册用户
    //返回1:注册失败(重名),0:成功,<0:服务器/数据库错误
    int sl_RegisterUser(QString userName, QString password, qint16 sex
                        , QByteArray ba, _SocketInfo::_SocketContext socketContext);

    //[ok!]
    //将 所有服务器信息 放入Buffer中
    //返回0:成功,<0:服务器/数据库错误
    int sl_GetGameServerInfoToBuffer(QByteArray ba, _SocketInfo::_SocketContext socketContext);

    //[ok!]
    //将 玩家游戏账户信息 放入Buffer中
    //返回0:成功,1:没有游戏账户信息,<0:服务器/数据库错误
    int sl_GetGameUserInfoToBuffer(quint32 userID, qint32 serverID, QString serverKey, QByteArray ba, _SocketInfo::_SocketContext socketContext);

    //注册 用户游戏信息,并将结果放入Buffer
    //返回0:成功,1:信息重复,<0:服务器/数据库错误
    int sl_RegisterGameUser(quint32 userID, qint32 serverID, QString nickName, qint16 sex, QByteArray ba, _SocketInfo::_SocketContext socketContext);



    //设置客户共享JSON数据
    //key:格式:$.xxx.yyy(对象)或$[index](数组);如果为空,则针对整个字段进行赋值(可以进行初始化);如果为$,则引用的是JSON根对象(如果不为NULL,则可以初始化)
    //data:自动识别Json的QString,QVariantMap,QVariantList,JS对象(QJSValue)
    int sl_SetClientShareExtraGameData(quint32 userGameID, QString key, QVariant data, QByteArray ba, _SocketInfo::_SocketContext socketContext);


    //[ok!]
    //更新 用户金币
    //返回0是成功,<0:服务器/数据库错误
    //int sl_UpdateScore(quint32 userGameID, qint16 achieve, qint32 scoreAdd
    //                       , QByteArray ba, _SocketInfo::_SocketContext socketContext);


    //插入 用户登录登出记录
    int sl_InsertUserOnlineLog(quint32 userGameID, qint16 clientType, quint32 ip, quint16 port, QDateTime dtLogin, QDateTime dtLogout);



//操作网络数据存储
//dataValue是识别data的字段
//key:格式:$.xxx.yyy(对象)或$[index](数组);如果为空,则针对整个字段进行赋值(可以进行初始化);如果为$,则引用的是JSON根对象(如果不为NULL,则可以初始化)
//data:自动识别QString,QVariantMap,QVariantList,JS对象(QJSValue)
//Get:返回JSON字符串
    int sl_SetClientGameData(quint32 userGameID, qint32 dataType, qint32 dataValue, QString key, QVariant data, qint32 r, QByteArray ba, _SocketInfo::_SocketContext socketContext);
    int sl_GetClientGameData(quint32 userGameID, qint32 dataType, qint32 dataValue, QString key, qint32 r, QByteArray ba, _SocketInfo::_SocketContext socketContext);
    int sl_DeleteClientGameData(quint32 userGameID, qint32 dataType, qint32 dataValue, qint32 r, QByteArray ba, _SocketInfo::_SocketContext socketContext);

    //以下2个基本没用
    int sl_InsertClientData(quint32 userGameID, qint32 dataType, qint32 dataValue, QVariant data, qint32 r, QByteArray ba, _SocketInfo::_SocketContext socketContext);
    int sl_UpdateClientData(quint32 userGameID, qint32 dataType, qint32 dataValue, QVariant data, qint32 r, QByteArray ba, _SocketInfo::_SocketContext socketContext);

    int sl_DBQuery(qint32 dataValue, QString strQuery, qint32 r, QByteArray ba, _SocketInfo::_SocketContext socketContext);


    //int sl_GetPetsInfoToBuffer(quint32 userGameID, QByteArray ba, _SocketInfo::_SocketContext socketContext);


public:
//protected:
    //bool bInited;
    Mysql *m_pMysql;
};

#endif // DATABASE_H
